import React, { useState, useCallback, useEffect } from 'react';
import { Common } from 'UtilsCommon';
import { useGetDataSourceOptions } from 'UseHooks';
import Base from './base';
import { Radio } from 'antd-mobile';

const getOptions = (property, view, pageAxis, parentValue) => {
    parentValue = parentValue || property.parentValue;

    Base.setValueTextName(property);
    const { valueName, textName, valueTextName } = property;

    const options = [];

    const { dataSource, emptyLabel } = property;

    let value = null; let text = null; let valueText = null;
    if (Common.isArray(dataSource)) {
        if (emptyLabel && dataSource.length > 0) options.push({ value: '', label: emptyLabel });

        dataSource.forEach(d => {
            text = d[textName];
            value = d[valueName];
            valueText = d[valueTextName];

            let isPush = false;
            if (property.judgePush) isPush = property.judgePush(d, parentValue, property, view);
            else isPush = Base.judgePush(d, parentValue, property, view);
            if (isPush) {
                options.push({ value, label: text, valueText });
            }
        });
    }

    return options;
};

const valueChange = (property, view, pageAxis, value) => {
    Base.childPropertiesChanged(property, view, value);
    if (property.valueChange) property.valueChange(value, Base.getSelectData(property, value), property);

    if (property.selectDataToProperties) Base.setSelectDataToProperties(property, view, Base.getSelectData(property, value));

    if (property.valueChangeEventActionName) {
        if (!Common.isEquals(property.value2, value)) {
            pageAxis.invokeEventAction(property.valueChangeEventActionName, { property, view, pageAxis });
        }
        property.value2 = value;
    }
};

const getText = (options, value) => {
    const item = Common.arrayFirst(options, (f) => Common.isEquals(f.value, value, true));
    if (item === null) return '';
    return item.valueText || item.label;
};

const offSvg = '<svg viewBox="0 0 48 48" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink><g id="DownFill-DownFill" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"><g id="DownFill-编组"><rect id="DownFill-矩形" fill="#FFFFFF" opacity="0" x="0" y="0" width="48" height="48"></rect><path d="M40.6640052,13 L7.34128264,13 C6.57572302,13 5.83336217,13.2619065 5.23947349,13.7351762 C3.80578911,14.8838891 3.58308085,16.9699517 4.74301968,18.3897608 L21.404381,38.7725222 C21.5528531,38.9517214 21.7152446,39.1171361 21.9008348,39.2641713 C23.3345192,40.4128842 25.4363283,40.1923313 26.6009069,38.7725222 L43.2576284,18.3897608 C43.740163,17.8016198 44,17.0664436 44,16.3082931 C44.004629,14.4795422 42.505988,13 40.6640052,13 Z" id="DownFill-路径" fill="currentColor" fill-rule="nonzero"></path></g></g></svg>';

export default (props) => {
    const { property, view, pageAxis } = Base.getProps(props);

    const [value, setValue] = useState(Base.getInitValue(property));
    const [isVisible, setIsVisible] = useState(property.isVisible !== false);
    const [options, setOptions] = useGetDataSourceOptions(property, view, pageAxis, getOptions, property.id);
    const [visible, setVisible] = useState(false);

    const onChange = useCallback((v) => {
        property.isChanged = true;
        setVisible(false);
        if (property.expandSetValue) property.expandSetValue(v, value, property);
        else {
            setValue(v);
            Base.bindDataValue(property, v);
        }
    }, [property, value, setValue, setVisible]);

    useEffect(() => {
        valueChange(property, view, pageAxis, value);
        if (property.valuePropertyName && !property.valueProperty) {
            property.valueProperty = pageAxis.getViewProperty(property, property.valuePropertyName);
        }
        if (property.valueProperty) {
            const t = value ? property.getText() : property.valueProperty.defaultValue || property.valueProperty.text;
            property.valueProperty.value = t;
            property.valueProperty.setValue && property.valueProperty.setValue(t);
        }
        property.isChanged = false;
    }, [property, view, pageAxis, value]);

    useEffect(() => {
        if (visible) {
            const fn = function () {
                visible && setVisible(false);
                document.body.removeEventListener('click', fn);
            };
            document.body.addEventListener('click', fn);
        }
    }, [visible, setVisible]);

    property.setIsVisible = (v) => { property.isVisible = v; setIsVisible(v); };
    property.setValue = (v) => setValue(v);
    property.getValue = () => Base.getValue(property, value);
    property.getSelectData = () => Base.getSelectData(property, value);
    property.setParentValue = (v) => setOptions(getOptions(property, view, pageAxis, v));
    property.refreshOptions = () => setOptions(getOptions(property, view, pageAxis));
    property.getText = () => getText(options, value);

    if (!isVisible) return null;

    const { style, className } = property;

    let options2 = options;
    if (property.getExpandOptions) options2 = property.getExpandOptions();
    const text = getText(options2, value);
    if (property.valueTextName) options2 = options2.filter(f => !Common.isNullOrEmpty(f.label));

    return (
        <div className={'divSelect ' + className} style={style}>
            <div className="divItem" style={Base.setStyle(property.itemStyle)} onClick={() => setVisible(!visible)}>
                <span className="spanText">{text}</span>
                <span className={visible && options2.length > 0 ? 'spanArrow arrowActive' : "spanArrow"} dangerouslySetInnerHTML={{ __html: offSvg }}>
                </span>
            </div>
            {options2.length > 0 && <div className='divOptionList' style={{ top: property.itemsTop, display: visible ? '' : 'none' }}>
                <Radio.Group value={Base.toString(value)} onChange={onChange}>
                    {options2.map((m, i) => <Radio key={i} value={Base.toString(m.value)}>{m.label}</Radio>)}
                </Radio.Group>
            </div>}
            {options2.length === 0 && <div className='divOptionList' style={{ top: property.itemsTop, display: visible ? '' : 'none' }}>
                <div className='divNoOptions'>{property.emptyOptionTip || '未有选项'}</div>
            </div>}
        </div>
    );
};